﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ArisanNgocok.Provider
{
   using System.Web.UI.WebControls;
   using Models;

   public class ServiceManager
   {
      public void GeneratePayment(int year, int month)
      {
         using (var db = new DataContext())
         {
            foreach (var user in db.Users)
               CreatePaymentEntry(db, user, year, month);

            db.SaveChanges();
         }
      }

      public IEnumerable<User> GetUsers()
      {
         using (var db = new DataContext())
         {
            return db.Users.ToList();
         }
      }

      public void CreateUser(string name)
      {
         using (var db = new DataContext())
         {
            db.Users.Add(new User
            {
               Name = name
            });
          
            db.SaveChanges();
         }
      }

      public void UpdateUser(Guid id, string name)
      {
         using (var db = new DataContext())
         {
            var user = db.Users.Find(id);
            if (user == null)
               throw new InvalidOperationException("Unable to find user with id " + id);

            user.Name = name;
            db.SaveChanges();
         }
      }

      public void UpdatePaymentStatus(Guid userId, int year, int month, bool isPaid)
      {
         using (var db = new DataContext())
         {
            if (!IsPaymentEntryCreated(db, userId, year, month))
               CreatePaymentEntry(db, userId, year, month);

            var payment    = GetPaymentEntry(db, userId, year, month);
            payment.IsPaid = isPaid;
            payment.ModifiedDate = DateTime.UtcNow;


            db.SaveChanges();
         }
      }

      public void TogglePaymentStatus(Guid paymentId)
      {
         using (var db = new DataContext())
         {
            var payment = db.Payments.Find(paymentId);
            if (payment != null)
            {
               payment.IsPaid       = !payment.IsPaid;
               payment.ModifiedDate = DateTime.UtcNow;
               db.SaveChanges();
            }
         }
      }

      private Payment GetPaymentEntry(DataContext db, Guid userId, int year, int month)
      {
         return db.Payments
            .Where(o => o.User.Id == userId)
            .Where(o => o.Year == year)
            .Where(o => o.Month == month)
            .FirstOrDefault();
      }

      private void CreatePaymentEntry(DataContext db, Guid userId, int year, int month)
      {
         var user = db.Users.Find(userId);
         if (user == null)
            throw new InvalidOperationException("Unable to find user with id " + userId);

         CreatePaymentEntry(db, user, year, month);
      }

      private void CreatePaymentEntry(DataContext db, User user, int year, int month)
      {
         if (IsPaymentEntryCreated(db, user.Id, year, month))
            return;

         var payment   = new Payment();
         payment.Year  = year;
         payment.Month = month;
         payment.User  = user;

         db.Payments.Add(payment);
      }

      private bool IsPaymentEntryCreated(DataContext db, Guid userId, int year, int month)
      {
         return db.Payments.Any(
            o => o.User.Id == userId
                 && o.Year == year
                 && o.Month == month
            );
      }
   }
}